
#include <iostream>
#include <string>
#include "syslog.h"

// #ifdef SWITCH_PLOG_
#define SWITCH_SPDLOG_

#ifdef SWITCH_PLOG_
#include "../plog/Log.h"
#include "../plog/Initializers/RollingFileInitializer.h"
#include "../plog/Formatters/TxtFormatter.h"
#include "../plog/Appenders/ColorConsoleAppender.h"
#include "../plog/Appenders/TextFileAppender.h"
#endif

#ifdef SWITCH_SPDLOG_
#include "spdlog/spdlog.h"
#include "spdlog/sinks/rotating_file_sink.h"
#endif

using namespace std;
using namespace equip_system::system_log;

/**
 * 初始化静态成员变量
 */
std::string CSysLog::m_lastLogContent = "";
std::mutex CSysLog::m_logMutex;

/**
 * 启动日志,文件大小限制5M=1024*1024*5,日志文件个数限制365*20
 * - fileName[in]：日志文件名称
 * - maxFileSize[in]：单个日志文件大小的上限；超过上限，则会自动创建新文件。
 * - maxFiles[in]：日志文件个数上限；超过上限，则会覆盖已有文件。
 */
int CSysLog::init(const char *fileName, size_t maxFileSize, int maxFiles)
{
// #define UTF8_FILE
#ifdef SWITCH_PLOG_

    // static plog::RollingFileAppender<plog::TxtFormatter> fileAppender(fileName, maxFileSize, maxFiles); // Create the 1st appender.
    static plog::RollingFileAppender<plog::TxtFormatter, plog::UTF8Converter>
        fileAppender(fileName, maxFileSize, maxFiles); // Create the 1st appender.

    // 初始化日志，使用自定义的文件输出器
    plog::init(plog::debug, &fileAppender); //
#endif

#ifdef SWITCH_SPDLOG_
    // 创建滚动日志sink（二进制模式+UTF-8）
    auto file_sink = std::make_shared<spdlog::sinks::rotating_file_sink_mt>(
        fileName, maxFileSize, maxFiles, true // 最后一个参数为true表示二进制模式
    );
    // 设置日志格式（支持UTF-8字符串）
    file_sink->set_pattern("[%Y-%m-%d %H:%M:%S] [%l] %v");
    // 初始化日志器
    auto logger = std::make_shared<spdlog::logger>("syslog", file_sink);
    spdlog::set_default_logger(logger);
    spdlog::set_level(spdlog::level::debug);

#endif
    return 0;
}

/**
 * 
 */
int CSysLog::print(log_level level, const char *tag, const char *format, ...)
{
    // 处理可变参数
    char buffer[1024];
    va_list args;
    va_start(args, format);
    int result = vsnprintf(buffer, sizeof(buffer), format, args);
    va_end(args);

    string _infor(tag);
    _infor.append(">>> ");
    _infor.append(buffer);

    // 关键修改：检查是否与上一次日志内容相同
    std::lock_guard<std::mutex> lock(m_logMutex); // 线程安全保护
    if (_infor == m_lastLogContent)
    {
        return 0; // 内容相同，不输出
    }
    m_lastLogContent = _infor; // 更新上一次日志内容

    cout << _infor << endl;

#ifdef SWITCH_PLOG_
    switch (level)
    {
    case LEVEL_INFO: //info
        PLOG_INFO << _infor;
        break;
    case LEVEL_WARNING: //warning
        PLOG_WARNING << _infor;
        break;
    case LEVEL_ERROR: //error
        PLOG_ERROR << _infor;
        break;
    case LEVEL_FATAL: //fatal
        PLOG_FATAL << _infor;
        break;
#ifdef EQUIP_DEBUG
    case LEVEL_DEBUG: //debug
        PLOG_DEBUG << _infor;
        break;
#endif
    case LEVEL_VERBOSE: //verbose
        PLOG_VERBOSE << _infor;
        break;
    case LEVEL_NONE: //none
        PLOG_NONE << _infor;
        break;
    }
#endif

#ifdef SWITCH_SPDLOG_

    switch (level)
    {
    case LEVEL_INFO:                           //info
        spdlog::info("{}", _infor); // 直接输出UTF-8内容
        break;
    case LEVEL_WARNING:                        //warning
        spdlog::warn("{}", _infor); // 直接输出UTF-8内容
        break;
    case LEVEL_ERROR:                          //error
        spdlog::error("{}", _infor); // 直接输出UTF-8内容
        break;
    case LEVEL_FATAL:                          //fatal
        spdlog::critical("{}", _infor); // 直接输出UTF-8内容
        break;
#ifdef EQUIP_DEBUG
    case LEVEL_DEBUG: //debug
        spdlog::debug("{}", _infor); // 直接输出UTF-8内容
        break;
#endif
    default:                           //none
        spdlog::trace("{}", _infor); // 直接输出UTF-8内容
        break;
    }

#endif

    return 0;
}
